home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 25 / AACD 25.iso / AACD / Magazine / Online / QMail / source / qmail-lspawn.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-04-15  |  5.4 KB  |  235 lines

  1. #include "fd.h"
  2. #include "wait.h"
  3. #include "prot.h"
  4. #include "substdio.h"
  5. #include "stralloc.h"
  6. #include "scan.h"
  7. #include "exit.h"
  8. #include "fork.h"
  9. #include "error.h"
  10. #include "cdb.h"
  11. #include "case.h"
  12. #include "slurpclose.h"
  13. #include "auto_qmail.h"
  14. #include "auto_uids.h"
  15. #include "qlx.h"
  16.  
  17. char *aliasempty;
  18.  
  19. void initialize(argc,argv)
  20. int argc;
  21. char **argv;
  22. {
  23.   aliasempty = argv[1];
  24.   if (!aliasempty) _exit(100);
  25. }
  26.  
  27. int truncreport = 3000;
  28.  
  29. void report(ss,wstat,s,len)
  30. substdio *ss;
  31. int wstat;
  32. char *s;
  33. int len;
  34. {
  35.  int i;
  36.  if (wait_crashed(wstat))
  37.   { substdio_puts(ss,"Zqmail-local crashed.\n"); return; }
  38.  switch(wait_exitcode(wstat))
  39.   {
  40.    case QLX_CDB:
  41.      substdio_puts(ss,"ZTrouble reading users/cdb in qmail-lspawn.\n"); return;
  42.    case QLX_NOMEM:
  43.      substdio_puts(ss,"ZOut of memory in qmail-lspawn.\n"); return;
  44.    case QLX_SYS:
  45.      substdio_puts(ss,"ZTemporary failure in qmail-lspawn.\n"); return;
  46.    case QLX_NOALIAS:
  47.      substdio_puts(ss,"ZUnable to find alias user!\n"); return;
  48.    case QLX_ROOT:
  49.      substdio_puts(ss,"ZNot allowed to perform deliveries as root.\n"); return;
  50.    case QLX_USAGE:
  51.      substdio_puts(ss,"ZInternal qmail-lspawn bug.\n"); return;
  52.    case QLX_NFS:
  53.      substdio_puts(ss,"ZNFS failure in qmail-local.\n"); return;
  54.    case QLX_EXECHARD:
  55.      substdio_puts(ss,"DUnable to run qmail-local.\n"); return;
  56.    case QLX_EXECSOFT:
  57.      substdio_puts(ss,"ZUnable to run qmail-local.\n"); return;
  58.    case QLX_EXECPW:
  59.      substdio_puts(ss,"ZUnable to run qmail-getpw.\n"); return;
  60.    case 111: case 71: case 74: case 75:
  61.      substdio_put(ss,"Z",1); break;
  62.    case 0:
  63.      substdio_put(ss,"K",1); break;
  64.    case 100:
  65.    default:
  66.      substdio_put(ss,"D",1); break;
  67.   }
  68.  
  69.  for (i = 0;i < len;++i) if (!s[i]) break;
  70.  substdio_put(ss,s,i);
  71. }
  72.  
  73. stralloc lower = {0};
  74. stralloc nughde = {0};
  75. stralloc wildchars = {0};
  76.  
  77. void nughde_get(local)
  78. char *local;
  79. {
  80.  char *(args[3]);
  81.  int pi[2];
  82.  int gpwpid;
  83.  int gpwstat;
  84.  int r;
  85.  int fd;
  86.  int flagwild;
  87.  
  88.  if (!stralloc_copys(&lower,"!")) _exit(QLX_NOMEM);
  89.  if (!stralloc_cats(&lower,local)) _exit(QLX_NOMEM);
  90.  if (!stralloc_0(&lower)) _exit(QLX_NOMEM);
  91.  case_lowerb(lower.s,lower.len);
  92.  
  93.  if (!stralloc_copys(&nughde,"")) _exit(QLX_NOMEM);
  94.  
  95.  fd = open_read("users/cdb");
  96.  if (fd == -1)
  97.    if (errno != error_noent)
  98.      _exit(QLX_CDB);
  99.  
  100.  if (fd != -1)
  101.   {
  102.    uint32 dlen;
  103.    unsigned int i;
  104.  
  105.    r = cdb_seek(fd,"",0,&dlen);
  106.    if (r != 1) _exit(QLX_CDB);
  107.    if (!stralloc_ready(&wildchars,(unsigned int) dlen)) _exit(QLX_NOMEM);
  108.    wildchars.len = dlen;
  109.    if (cdb_bread(fd,wildchars.s,wildchars.len) == -1) _exit(QLX_CDB);
  110.  
  111.    i = lower.len;
  112.    flagwild = 0;
  113.  
  114.    do
  115.     {
  116.      /* i > 0 */
  117.      if (!flagwild || (i == 1) || (byte_chr(wildchars.s,wildchars.len,lower.s[i - 1]) < wildchars.len))
  118.       {
  119.        r = cdb_seek(fd,lower.s,i,&dlen);
  120.        if (r == -1) _exit(QLX_CDB);
  121.        if (r == 1)
  122.         {
  123.          if (!stralloc_ready(&nughde,(unsigned int) dlen)) _exit(QLX_NOMEM);
  124.          nughde.len = dlen;
  125.          if (cdb_bread(fd,nughde.s,nughde.len) == -1) _exit(QLX_CDB);
  126.          if (flagwild)
  127.        if (!stralloc_cats(&nughde,local + i - 1)) _exit(QLX_NOMEM);
  128.          if (!stralloc_0(&nughde)) _exit(QLX_NOMEM);
  129.          close(fd);
  130.          return;
  131.         }
  132.       }
  133.      --i;
  134.      flagwild = 1;
  135.     }
  136.    while (i);
  137.  
  138.    close(fd);
  139.   }
  140.  
  141.  if (pipe(pi) == -1) _exit(QLX_SYS);
  142.  args[0] = "bin/qmail-getpw";
  143.  args[1] = local;
  144.  args[2] = 0;
  145.  switch(gpwpid = vfork())
  146.   {
  147.    case -1:
  148.      _exit(QLX_SYS);
  149.    case 0:
  150.      if (prot_gid(auto_gidn) == -1) _exit(QLX_USAGE);
  151.      if (prot_uid(auto_uidp) == -1) _exit(QLX_USAGE);
  152.      close(pi[0]);
  153.      if (fd_move(1,pi[1]) == -1) _exit(QLX_SYS);
  154.      execv(*args,args);
  155.      _exit(QLX_EXECPW);
  156.   }
  157.  close(pi[1]);
  158.  
  159.  if (slurpclose(pi[0],&nughde,128) == -1) _exit(QLX_SYS);
  160.  
  161.  if (wait_pid(&gpwstat,gpwpid) != -1)
  162.   {
  163.    if (wait_crashed(gpwstat)) _exit(QLX_SYS);
  164.    if (wait_exitcode(gpwstat) != 0) _exit(wait_exitcode(gpwstat));
  165.   }
  166. }
  167.  
  168. int spawn(fdmess,fdout,s,r,at)
  169. int fdmess; int fdout;
  170. char *s; char *r; int at;
  171. {
  172.  int f;
  173.  
  174.  if (!(f = fork()))
  175.   {
  176.    char *(args[11]);
  177.    unsigned long u;
  178.    int n;
  179.    int uid;
  180.    int gid;
  181.    char *x;
  182.    unsigned int xlen;
  183.    
  184.    r[at] = 0;
  185.    if (!r[0]) _exit(0); /* <> */
  186.  
  187.    if (chdir(auto_qmail) == -1) _exit(QLX_USAGE);
  188.  
  189.    nughde_get(r);
  190.  
  191.    x = nughde.s;
  192.    xlen = nughde.len;
  193.  
  194.    args[0] = "bin/qmail-local";
  195.    args[1] = "--";
  196.    args[2] = x;
  197.    n = byte_chr(x,xlen,0); if (n++ == xlen) _exit(QLX_USAGE); x += n; xlen -= n;
  198.  
  199.    scan_ulong(x,&u);
  200.    uid = u;
  201.    n = byte_chr(x,xlen,0); if (n++ == xlen) _exit(QLX_USAGE); x += n; xlen -= n;
  202.  
  203.    scan_ulong(x,&u);
  204.    gid = u;
  205.    n = byte_chr(x,xlen,0); if (n++ == xlen) _exit(QLX_USAGE); x += n; xlen -= n;
  206.  
  207.    args[3] = x;
  208.    n = byte_chr(x,xlen,0); if (n++ == xlen) _exit(QLX_USAGE); x += n; xlen -= n;
  209.  
  210.    args[4] = r;
  211.    args[5] = x;
  212.    n = byte_chr(x,xlen,0); if (n++ == xlen) _exit(QLX_USAGE); x += n; xlen -= n;
  213.  
  214.    args[6] = x;
  215.    n = byte_chr(x,xlen,0); if (n++ == xlen) _exit(QLX_USAGE); x += n; xlen -= n;
  216.  
  217.    args[7] = r + at + 1;
  218.    args[8] = s;
  219.    args[9] = aliasempty;
  220.    args[10] = 0;
  221.  
  222.    if (fd_move(0,fdmess) == -1) _exit(QLX_SYS);
  223.    if (fd_move(1,fdout) == -1) _exit(QLX_SYS);
  224.    if (fd_copy(2,1) == -1) _exit(QLX_SYS);
  225.    if (prot_gid(gid) == -1) _exit(QLX_USAGE);
  226.    if (prot_uid(uid) == -1) _exit(QLX_USAGE);
  227.    if (!getuid()) _exit(QLX_ROOT);
  228.  
  229.    execv(*args,args);
  230.    if (error_temp(errno)) _exit(QLX_EXECSOFT);
  231.    _exit(QLX_EXECHARD);
  232.   }
  233.  return f;
  234. }
  235.